"Les cours de neeko.fr"

Retour en haut

Android et ses System Services

Android et ses System-Services

Utiliser le téléphone et ses outils

Quelques "System-Services"

Un terminal Android possède souvent de nombreuses fonctionnalités : un acceléromètre, un GPS, un vibreur, un lecteur NFC (Near Field Communication), et bien d'autres.

Chacuns de ces éléments est représenté par une classe particulière, qui permet de lire et de controller le matériel.

Ces classes sont toutes très différentes, mais sont toutes récupérées de la même manière : avec la méthode getSystemService(nomduservice)

Les services sont partagés entre toutes les applications. Certaines applications peuvent les modifier pendant l'exécution de notre programme.

Quelques services et leur classe associée :

Code du serviceNom de la classeQuelques possibilités
TELEPHONY_SERVICETelephonyManagerPour savoir si le téléphone est décroché, connaître l'opérateur, le numéro de série de la carte SIM...
DISPLAY_SERVICEDisplayManagerRécupérer la liste des écrans connectés...
AUDIO_SERVICEAudioManagerVérifier et controller le niveau sonnore, jouer des sons "systemes", ...
ALARM_SERVICEAlarmManagerDemander au système de lancer l'application à une heure précise, ...
ACTIVITY_SERVICEActivityManagerAccéder à la liste des processus lancés, accéder à des information sur la mémoire, ...
USB_SERVICEUsbManager(API 12) Accéder a des informations si un accéssoire est connecté, communiquer avec un accéssoire, ...
LOCATION_SERVICELocationManagerConnaitre la position GPS du téléphone, être notifié d'un déplacement du téléphone.
VIBRATOR_SERVICEVibratorActiver le vibreur.
LAYOUT_INFLATER_SERVICELayoutInflaterUtiliser dynamiquement des layouts

Tous les services sur la documentation de la classe Context (dont Activity hérite) : http://developer.android.com/reference/android/content/Context.html

A noter que l'utilisation de ces services demandes souvent la déclaration de permissions dans le manifest.

Pour info, la liste complète des permissions se trouve aussi sur la doc d'Android : http://developer.android.com/reference/android/Manifest.permission.html

Par exemple, pour accéder à une instance du service "VIBRATOR_SERVICE", il faut, dans une activity :

Vibrator vibratorService = (Vibrator) this.getSystemService(VIBRATOR_SERVICE);

Ensuite, il est possible d'acceder aux méthodes de cette classe, par exemple :

Vibrator vibratorService = (Vibrator) this.getSystemService(VIBRATOR_SERVICE); if (vibratorService.hasVibrator()) { vibratorService.vibrate(1000); }

Le LOCATION_SERVICE

Le LOCATION_SERVICE permet de connaitre et de suivre la géolocalisation du terminal grace à la puce GPS ou au réseau cellulaire (moins précis).

La géolocalisation est représentée par un objet Location, qui contient (entre autre) des méthodes getLatitude() et getLongitude().

Pré-requis

L'utilisation de ce service nécessite :

Le principe

Dernière position connue

La classe LocationManager permet d'accéder aux fournisseurs de position : GPS_PROVIDER, NETWORK_PROVIDER ou PASSIVE_PROVIDER.

Le moyen le plus simple est d'espérer qu'une autre application à déja utilisé le service et de simplement demander quelle est la derniere position connue, ce qui permet d'économiser l'énergie, puisque cette méthode n'active aucun matériel particulier.

LocationManager lm = (LocationManager) this.getSystemService(LOCATION_SERVICE); Location lastGpsLoc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER)); Location lastNetLoc = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)); if (lastGpsLoc != null) { System.out.println("Derniere position connue (GPS) : "); System.out.println("Latitude: " + lastGpsLoc.getLatitude()); System.out.println("Longitude: " + lastGpsLoc.getLongitude()); } if (lastNetLoc != null) { System.out.println("Derniere position connue (NETWORK) : "); System.out.println("Latitude: " + lastGpsLoc.getLatitude()); System.out.println("Longitude: " + lastGpsLoc.getLongitude()); }

Activer les notifications

Pour activer et être notifié de la position réelle du terminal, il faut utiliser l'interface LocationListener. Les méthodes de cette interface sont :

void onLocationChanged(Location newLocalisation); void onProviderDisabled(String provider); void onProviderEnabled(String provider); void onStatusChanged(String provider, int status, Bundle extras);

Il suffit alors d'utiliser la méthode requestLocationUpdates(...) du service pour demander à être notifié des changements de position en lui passant une classe qui implémente cette interface. Cela peut être l'activity, ou une autre classe crée pour l'occasion.

La signature de la méthode :

void requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener); //String provider : le fournisseur (GPS, NETWORK ou PASSIVE) //long minTime : temps minimal entre chaque notification (en ms) //float minDistance : la distance minimale entre chaque notification (en m). //LocationListener listener : l'objet qui sera notifié.

LocationManager lm = (LocationManager) this.getSystemService(LOCATION_SERVICE); lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 0, this); lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10000, 0, this);

Il est aussi possible de se désabonner de ces notifications :

lm.removeUpdates(this);

Exemple complet :

package com.example.geoloctest1; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.app.Activity; import android.util.Log; public class MainActivity extends Activity implements LocationListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); LocationManager lm = (LocationManager) this.getSystemService(LOCATION_SERVICE); lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this); } @Override public void onLocationChanged(Location newLoc) { System.out.println("Nouvelle position : " + newLoc.getLatitude() + ", " + newLoc.getLongitude()); } @Override public void onProviderDisabled(String provider) { System.out.println("Fournisseur desactive : "+ provider); } @Override public void onProviderEnabled(String provider) { System.out.println("Fournisseur active : "+ provider); } @Override public void onStatusChanged(String provider, int status, Bundle extras) { System.out.println("Status change : " + provider + " = " + status); } }

Tester sur le simulateur

Il est possible de simuler des déplacements pour le simulateur, ainsi que d'autres actions.

Il faut pour cela utiliser la vue "DDMS" dans Eclipse.

Cette vue nous permet d'accéder à un onglet "Emulator Control", qui nous permet d'envoyer des ordres au simulateur pour voir comment notre application réagit : Changer le l'état de la connection réseau, simuler un appel entrant ou envoyer une position au GPS.

Exercice 1

Réaliser une application qui affiche la géolocalisation actuelle (latitude, longitude) dans une TextView.

Etapes

  • Créer un nouveau projet "GeolocTest", en prenant soin de choisir "Google API", à la place de Android 2.3.3.
  • S'assurer que l'émulateur est correctement configuré : dans le AVD manager, on peut éditer les détails de chaque simulateur. Il faut que le "target" corresponde aussi à Google API.
  • Ajouter les permissions nécessaires dans le manifest.
  • Modifier le layout de l'activity pour ajouter un "id" au TextView déja présent.
  • Dans la méthode "onCreate" de l'activity, récupérer le systemService nécessaire.
  • Essayer de récuperer les dernieres position connues : si une est accessible, afficher cette position à l'écran (dans le TextView), en précisant qu'elle est incertaine.
  • Appeller la méthode "requestLocationUpdates" pour le provider GPS et NETWORK, en passant l'Activity... Eclipse indiquera une erreur, c'est normal car...
  • Implémenter l'interface "LocationListener" dans l'activity... Eclipse indiquera une erreur, c'est normal car...
  • Implémenter effectivement les méthodes de l'interface. La méthode "onLocationChanged" sera appellée à chaque changement. Elle doit alors gérer l'affichage de la nouvelle position dans le TextView.
  • Tester en envoyant des fausses valeurs grace au DDMS.
  • Annexes

    Permissions:

    A placer juste avant la balise "application".

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

    Exercice 2

    Intégrer la géolocalisation dans l'application météo

  • Récupérer le projet "WeatherForecast"
  • Modifier la "target" du projet en choississant "Google API" pour la version 2.3.3.
  • Ajouter les permissions dans le manifest.
  • Dans la méthode "onCreate" de l'activity, récupérer le systemService nécessaire.
  • Appeller la méthode "requestLocationUpdates" pour le provider GPS et NETWORK, en passant l'Activity... Eclipse indiquera une erreur, c'est normal car...
  • Implémenter l'interface "LocationListener" dans l'activity... Eclipse indiquera une erreur, c'est normal car...
  • Implémenter effectivement les méthodes de l'interface. Dans la méthode "onLocationChanged", appeller le "makeForecast" du "Forecaster" avec la "Location" reçue.
  • Tester en envoyant des valeurs grace au DDMS, ou partez en voyage avec votre téléphone Android !
  • Annexes

    Changer la "target" d'un projet:

    Sélectionner le projet, puis bouton droit "properties". Dans la catégorie "Android", la liste des "target" apparait à droite.

    Exemples de géolocalisations
  • Aix en provence : latitude=43.529742 longitude=5.447427
  • Paris : latitude=48.86 longitude=2.34